package com.showsu.editor.job;


import cn.hutool.core.collection.CollectionUtil;
import com.showsu.editor.config.SpringContextUtil;
import com.showsu.editor.entity.doo.RemoteInterfaceInfo;
import com.showsu.editor.entity.doo.RemoteInterfaceSwitchRecord;
import com.showsu.editor.entity.doo.SysDict;
import com.showsu.editor.entity.platform.xhs.XhsAwemeDetailResult;
import com.showsu.editor.entity.po.TblRemoteInterfaceSwitchRecord;
import com.showsu.editor.entity.remote.WhoseCardVideoDetailResp;
import com.showsu.editor.enums.InterfaceSwitchStatusEnum;
import com.showsu.editor.enums.RemoteInterfaceEnum;
import com.showsu.editor.service.IRemoteInterfaceInfoService;
import com.showsu.editor.service.IRemoteInterfaceSwitchRecordService;
import com.showsu.editor.service.ISysDictService;
import com.showsu.editor.utils.Constant;
import com.showsu.editor.utils.DateUtil;
import com.showsu.editor.utils.RemoteIntegrationUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: William
 * @Description: 平台接口自动切换任务
 * @Date: Created in 9:48 上午 2024/3/11
 * @Modified By:
 */
@Component
@Slf4j
public class InterfaceAutoSwitchSchedule {

    private static final String XHS_LIVE_NOTE_ID = "65eefc2700000000120219c2";
    private static final String XHS_LIVE_NOTE_XSECTOKEN ="CBRduaAIF1PyDIQ5q626nccIHlNF3RW5APYb2B450JiqM=";
    private static final String DY_LIVE_AWEME_ID = "7413745599616404773";

    @Autowired
    private ISysDictService sysDictService;

    @Autowired
    private IRemoteInterfaceInfoService remoteInterfaceInfoService;

    @Autowired
    private IRemoteInterfaceSwitchRecordService remoteInterfaceSwitchRecordService;

    @Autowired
    private RemoteIntegrationUtil remoteIntegrationUtil;

    @Scheduled(cron = "0 0/2 * * * ? ")
    @Transactional
    public void execute() {
        Environment environment = SpringContextUtil.getApplicationContext().getEnvironment();
        //开发、测试环境暂不开启，有需要自行注释
        if (!"prod".equals(environment.getActiveProfiles()[0]) ) {
            return;
        }
        //0.检查自动切换的开关是否开启
        SysDict autoSwitch = sysDictService.queryByAppIdAndKey(Constant.system, Constant.interfaceAutoSwitch);
        if (autoSwitch == null
                || StringUtils.isBlank(autoSwitch.getDictValue())
                || !autoSwitch.getDictValue().equals(Constant.oneString)) {
            return;
        }
        //1.检查是否在自动切换的时间段内
        SysDict autoTime = sysDictService.queryByAppIdAndKey(Constant.system, Constant.interfaceAutoTime);
        if (autoTime == null
                || StringUtils.isBlank(autoTime.getDictValue())
                || (! DateUtil.checkTimeRangeAvailable(autoTime.getDictValue()))) {
            return;
        }
        log.info("InterfaceAutoSwitchSchedule.execute()，在有效的检查时间段内，autoTime:{}", autoTime);
        //2.检查最近15分钟内是否有自动切换接口的需求
        Date last15Mins = DateUtil.addMinutes(new Date(), -15);
        List<RemoteInterfaceSwitchRecord> recordListInLast15Mins = remoteInterfaceSwitchRecordService.queryLastSwitchRecordInRecentTimesGroupByInterfaceId(last15Mins);
        if (CollectionUtil.isEmpty(recordListInLast15Mins)) {
            return;
        }
        List<RemoteInterfaceSwitchRecord> needRetryRecordList = recordListInLast15Mins
                .stream()
                .filter(item ->
                        !item.getStatus().equals(InterfaceSwitchStatusEnum.DONE.getCode())
                                && !item.getStatus().equals(InterfaceSwitchStatusEnum.STOP.getCode()))
                .collect(Collectors.toList());
        if (CollectionUtil.isEmpty(needRetryRecordList)) {
            return;
        }
        log.info("InterfaceAutoSwitchSchedule.execute()，检测到{}条接口切换需求", needRetryRecordList.size());
        for (RemoteInterfaceSwitchRecord remoteInterfaceSwitchRecord : needRetryRecordList) {
            if (StringUtils.isBlank(remoteInterfaceSwitchRecord.getQueryParams())) {
                continue;
            }
            TblRemoteInterfaceSwitchRecord newRecord = new TblRemoteInterfaceSwitchRecord();
            BeanUtils.copyProperties(remoteInterfaceSwitchRecord, newRecord);
            //如果同interface_name正在使用的接口，跟重试中的接口不同，代表有人手动切换了接口，这时候终止重试流程
            RemoteInterfaceInfo usingRemoteInterfaceInfo = remoteInterfaceInfoService.queryUsingInterfaceInfo(remoteInterfaceSwitchRecord.getInterfaceName());
            if (usingRemoteInterfaceInfo != null && !usingRemoteInterfaceInfo.getInterfaceId().equals(remoteInterfaceSwitchRecord.getInterfaceId())) {
                saveRemoteInterfaceSwitchRecord(newRecord, InterfaceSwitchStatusEnum.STOP.getCode());
                log.info("InterfaceAutoSwitchSchedule.execute()，接口类型{}、接口id{} 发现有人手动完成了切换，切换后的接口id{}，停止重试流程",
                        remoteInterfaceSwitchRecord.getInterfaceName(), remoteInterfaceSwitchRecord.getInterfaceId(), usingRemoteInterfaceInfo.getInterfaceId());
                continue;
            }
            //重试成功，则停止重试流程
            if (checkInterfaceAvailable(remoteInterfaceSwitchRecord.getInterfaceId(), remoteInterfaceSwitchRecord.getInterfaceName())) {
                saveRemoteInterfaceSwitchRecord(newRecord, InterfaceSwitchStatusEnum.STOP.getCode());
                log.info("InterfaceAutoSwitchSchedule.execute()，接口类型{}、接口id{}重试成功，停止重试流程", remoteInterfaceSwitchRecord.getInterfaceName(), remoteInterfaceSwitchRecord.getInterfaceId());
                continue;
            }
            //若重试5次都失败，则启动切换；若不足5次，继续等待重试
            if (remoteInterfaceSwitchRecord.getTimes() < (Constant.interfaceAutoSwitchRetryTimes - 1)) {
                saveRemoteInterfaceSwitchRecord(newRecord, InterfaceSwitchStatusEnum.DOING.getCode());
                log.info("InterfaceAutoSwitchSchedule.execute()，接口类型{}、接口id{}的第{}次重试失败，等待下一次重试", remoteInterfaceSwitchRecord.getInterfaceName(),
                        remoteInterfaceSwitchRecord.getInterfaceId(), newRecord.getTimes());
                continue;
            }
            //检查是否存在可切换的接口
            List<RemoteInterfaceInfo> autoInterfaceInfoList = remoteInterfaceInfoService.queryAutoSwitchInterfacesBySameInterface(remoteInterfaceSwitchRecord.getInterfaceId());
            if (CollectionUtil.isEmpty(autoInterfaceInfoList)) {
                saveRemoteInterfaceSwitchRecord(newRecord, InterfaceSwitchStatusEnum.STOP.getCode());
                log.info("InterfaceAutoSwitchSchedule.execute()，接口类型{}不存在可切换的接口，结束流程", remoteInterfaceSwitchRecord.getInterfaceName());
                continue;
            }
            boolean switchResult = false;
            for (RemoteInterfaceInfo remoteInterfaceInfo : autoInterfaceInfoList) {
                if (remoteInterfaceInfo.getInterfaceId().equals(remoteInterfaceSwitchRecord.getInterfaceId())) {
                    continue;
                }
                //接口成功获取到数据，则进行切换动作
                if (checkInterfaceAvailable(remoteInterfaceInfo.getInterfaceId(), remoteInterfaceInfo.getInterfaceName())) {
                    log.info("InterfaceAutoSwitchSchedule.execute()，接口类型{}、接口id{}验证成功，操作切换，切换后结束流程", remoteInterfaceInfo.getInterfaceName(), remoteInterfaceInfo.getInterfaceId());
                    //正在使用的接口置为不在使用状态
                    remoteInterfaceInfoService.updateActiveToUnavailableByInterfaceName(remoteInterfaceSwitchRecord.getInterfaceName());
                    //切换接口
                    remoteInterfaceInfoService.updateActiveByInterfaceId(remoteInterfaceInfo.getInterfaceId(), 1);
                    switchResult = true;
                    break;
                } else {
                    log.info("InterfaceAutoSwitchSchedule.execute()，接口类型{}、接口id{}验证失败，继续对下一个接口进行验证", remoteInterfaceInfo.getInterfaceName(), remoteInterfaceInfo.getInterfaceId());
                }
            }
            if (!switchResult) {
                log.info("InterfaceAutoSwitchSchedule.execute()，接口类型{}重试了所有的可切换接口均失败，结束流程", remoteInterfaceSwitchRecord.getInterfaceName());
            }
            //更新记录状态为已完成
            saveRemoteInterfaceSwitchRecord(newRecord, InterfaceSwitchStatusEnum.DONE.getCode());
        }
    }

    private Boolean checkInterfaceAvailable(Long interfaceId, String interfaceName) {
        try {
            switch (RemoteInterfaceEnum.getByName(interfaceName.toUpperCase())) {
                case XHS_AWEME_DETAIL_FOR_LIVE:
                    XhsAwemeDetailResult xhsAwemeDetailForLive = remoteIntegrationUtil.getXhsAwemeDetailForLive(XHS_LIVE_NOTE_ID, XHS_LIVE_NOTE_XSECTOKEN, interfaceId);
                    if (xhsAwemeDetailForLive != null && xhsAwemeDetailForLive.getData() != null && xhsAwemeDetailForLive.getData().getData() != null) {
                        return true;
                    }
                    return false;
                case DY_AWEME_DETAIL_FOR_LIVE:
                    WhoseCardVideoDetailResp dyAwemeDetailForLive = remoteIntegrationUtil.getDyAwemeDetailForLive(DY_LIVE_AWEME_ID, interfaceId);
                    if (dyAwemeDetailForLive != null && dyAwemeDetailForLive.getResult() != null && dyAwemeDetailForLive.getResult().getAweme_detail() != null) {
                        return true;
                    }
                    return false;
                default:
                    return false;
            }
        } catch (Exception e) {
            log.error("InterfaceAutoSwitchSchedule.checkInterfaceAvailable(...) error", e);
        }
        return false;
    }

    private void saveRemoteInterfaceSwitchRecord(TblRemoteInterfaceSwitchRecord record, Integer status) {
        record.setId(null);
        record.setTimes(record.getTimes() + 1);
        record.setStatus(status);
        remoteInterfaceSwitchRecordService.save(record);
    }
}
